#include "crc.h"

// 1. CRC 表的定义（在 .cpp，仅一次）
const std::array<CrcModbus16::value_type, 256> CrcModbus16::kTable = [] {
  std::array<value_type, 256> table{};
  for (std::size_t i = 0; i < 256; ++i) {
    value_type c = static_cast<value_type>(i);
    for (int j = 0; j < 8; ++j)
      c = (c & 1) ? (c >> 1) ^ 0xA001 : (c >> 1);
    table[i] = c;
  }
  return table;
}(); // 立即执行 lambda 得到 table

// 2. 成员函数实现
CrcModbus16::CrcModbus16(value_type initial) noexcept : crc_(initial) {}
void CrcModbus16::reset() noexcept { crc_ = 0xFFFF; }
CrcModbus16::value_type CrcModbus16::value() const noexcept { return crc_; }
CrcModbus16::value_type CrcModbus16::finalize() const noexcept { return crc_; }

void CrcModbus16::update(std::uint8_t byte) noexcept {
  crc_ ^= byte;
  crc_ = static_cast<value_type>((crc_ >> 8) ^ kTable[crc_ & 0xFF]);
}

void CrcModbus16::update(const std::uint8_t *data, std::size_t len) noexcept {
  for (std::size_t i = 0; i < len; ++i)
    update(data[i]);
}

CrcModbus16::value_type CrcModbus16::calculate(const std::uint8_t *data,
                                               std::size_t len) noexcept {
  CrcModbus16 ctx;
  ctx.update(data, len);
  return ctx.finalize();
}

CrcModbus16::value_type
CrcModbus16::operator()(std::initializer_list<std::uint8_t> il) const noexcept {
  return calculate(il.begin(), il.size());
}